package com.apache.ius.controller;

import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.ius.common.CommonUtils;
import com.apache.ius.common.annotion.BeanFactory;
import com.apache.ius.common.connectors.impl.AdapterFactory;
import com.apache.tools.ConfigUtil;
import com.apache.tools.RequestTools;
import com.apache.tools.StrUtil;
import com.apache.uct.common.ToolsUtil;
import net.sf.json.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * description:  为第三方客户端提供统一请求接口地址
 */
public class SuperApiAction extends BaseAction {

    /**
     * get 统一入口方法
     * header: { 'content-type': 'application/x-www-form-urlencoded、application/json' },
     */
    @RequestMapping(value = {"/info/","/list/"}, method = RequestMethod.GET)
    @ResponseBody
    public void doGetInvoke(HttpServletRequest request,HttpServletResponse response)  throws Exception {
        if(!validUserKey(request)){
            gotoErrorPage(request, response, "服务端userKeys身份验证失败");
            return;
        }
        String doCode = StrUtil.doNull(request.getParameter("doCode"), "dymicSql");
        String uri = request.getRequestURI().replaceAll(request.getContextPath(),"");
        Method method = doInvoke(this.getClass(), request, response, uri, doCode);
        try {
            if (null != method) {
                log.info("doInvoke method-->"+method.getName());
                Object obj = method.invoke(this, request, response);
                if (!ToolsUtil.isEmpty(obj)) {
                    JSONObject array = JSONObject.fromObject(obj);
                    request.setAttribute(BeanFactory.RETURN_MSG_KEY,array.toString());
                    this.outputJson(array.toString(),response,"");
                }
            } else {
                gotoErrorPage(request, response, "请求的Action地址未定义");
            }
        }catch (Exception e){
            log.error("执行失败(doInvoke)：", e);
            gotoErrorPage(request, response, "执行失败，请重试："+e.getMessage());
        }
    }

    /**
     * post 统一入口方法
     * header: { 'content-type': 'application/json' },
     */
    @RequestMapping(value = {"/submit/"}, method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void doPostInvoke(HttpServletRequest request, HttpServletResponse response,@RequestBody Map<String, Object> requestBody) throws Exception {
        String doCode = StrUtil.doNull(request.getParameter("doCode"), "dymicSql");
        if(!validUserKey(request)){
            gotoErrorPage(request, response, "服务端userKeys身份验证失败");
            return;
        }
        Map<String, String> params = this.getParameterMapByJson(request,requestBody);
        log.info("client request params-->"+params);
        params.remove("userKeys");

        try {
            params.put("resultType", "processSql");
            Map<String, Object> result = new HashMap<String, Object>();
            params = AdapterFactory.getInstance()
                    .getReqParamForBefor("setReqParam,createInfo", params, request, response);//前拦截
            String execptionMsg = String.valueOf(params.get("execptionMsg"));
            if (StrUtil.isNotNull(execptionMsg)) {
                ResultMsg msg = new ResultMsg("F", execptionMsg);
                JSONObject array = JSONObject.fromObject(msg);
                this.outputJson(array.toString(),response,"");
                return;
            }
            ParamsVo vo = new ParamsVo();
            vo.setParams(params);
            vo.setMethodKey("dymicSql");
            ResultEntity entity = doIusService(vo);
            result = super.getResultEntityData(entity);
            if (!ToolsUtil.isEmpty(result)) {
                JSONObject array = JSONObject.fromObject(result);
                this.outputJson(array.toString(),response,"");
            }
        }catch (Exception e){
            log.error("执行失败(doInvoke)：", e);
            gotoErrorPage(request, response, "执行失败，请重试："+e.getMessage());
        }
    }

    /**
     *统一判断身份
     */
    protected boolean validUserKey(HttpServletRequest request){
        boolean flag = false;
        String userKeys = request.getParameter("userKeys");//接口验证串
        String client_to_pass= CommonUtils.getConfigVal("client_to_pass");
        log.info("-");
        log.info("client request url -->"+ request.getRequestURI());
        log.info("client request parameter [userKeys]-->"+userKeys);
        log.info("server config [client_to_pass]-->"+client_to_pass);

        if (!StrUtil.doNull(client_to_pass, "ius").equalsIgnoreCase(userKeys)) {
            flag = false;
        }else{
            flag = true;
        }
        log.info("server validation [userKeys] results-->"+flag);
        return flag;
    }

    /**
     * 查询标的列表
     */
    @RequestMapping(value = "/api/info/dymicSql", method = RequestMethod.GET)
    @ResponseBody
    public Object infoDymicSql(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        Map<String, String> params = this.getParameterMap(request);
        log.info("client request params-->"+params);
        params.remove("userKeys");
        params.put("ifDataAct","F");//是否使用数据权限,只有ifData=F才不走数据权限
        params.put("resultType", StrUtil.doNull(request.getParameter("resultType"), "objInfo"));
        params.put("resultObjType", "obj");
        params = AdapterFactory.getInstance()
                .getReqParamForBefor("setReqParam", params, request, response);//前拦截
        String execptionMsg = String.valueOf(params.get("execptionMsg"));
        if (StrUtil.isNotNull(execptionMsg)) {
            ResultMsg msg = new ResultMsg("F", execptionMsg);
            JSONObject array = JSONObject.fromObject(msg);
            return array;
        }
        ParamsVo vo = new ParamsVo();
        vo.setParams(params);
        vo.setMethodKey("dymicSql");
        ResultEntity entity = doIusService(vo);//.doInvoke(request, response,
                //params);
        Map<String, Object>  resultMap = getResultEntityData(entity);
//        System.out.println(resultMap);
//        JSONObject array =null;
//        if (null == entity.getEntity()) {
//            log.error("获取失败：" + entity.getMessage());
//        } else {
//            if (entity.getEntity() instanceof String) {
//                ResultMsg msg = new ResultMsg("F", entity.getMessage());
//                array = JSONObject.fromObject(msg);
//            } else {
//                array = JSONObject.fromObject(entity.getEntity());
//            }
//        }
        return resultMap;
    }

    /**
     * 查询列表
     */
    @RequestMapping(value = "/api/list/dymicSql", method = RequestMethod.GET)
    @ResponseBody
    public Object listDymicSql(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        Map<String, String> params = this.getParameterMap(request);
        log.info("client request params-->"+params);
        params.remove("userKeys");
        params.put("ifDataAct","F");//是否使用数据权限,只有ifData=F才不走数据权限
        String modelTypes = params.get("modelTypes");
        //如果不传modelTypes，还是沿用以前自己写sql的方式，否则走ius的公共方法。
        params.put("resultType", StrUtil.doNull(request.getParameter("resultType"), "objInfo"));
        params.put("resultObjType", "list");
        params = AdapterFactory.getInstance()
                .getReqParamForBefor("setReqParam", params, request, response);//前拦截
        String execptionMsg = String.valueOf(params.get("execptionMsg"));
        if (StrUtil.isNotNull(execptionMsg)) {
            ResultMsg msg = new ResultMsg("F", execptionMsg);
            JSONObject array = JSONObject.fromObject(msg);
            return array;
        }
        ParamsVo vo = new ParamsVo();
        vo.setParams(params);
        vo.setMethodKey("dymicSql");
        ResultEntity entity = doIusService(vo);
        Map<String, Object> resultMap = new HashMap<String, Object>();
        if (null == entity.getEntity()) {
            log.error("获取失败：" + entity.getMessage());
        } else {
            //            if (null != entity.getEntity()) {
            //                oscache.put(cacheKey, entity);
            //            }
            if ("RelationByProId".equals(request.getParameter("sqlKeyId"))) {
                resultMap.put("dealFlag", "T");//需特殊处理
            }
            getListData(entity, resultMap);
        }
        //JSONObject array = JSONObject.fromObject(resultMap);
        return resultMap;
    }

    /**
     *

    @RequestMapping(value = "/api/submit/dymicSql", method = RequestMethod.POST)
    @ResponseBody
    public Object submitDymicSql(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String, String> params = this.getParameterMap(request);
        log.info("client request params-->"+params);
        params.remove("userKeys");

        params.put("resultType", "processSql");
        Map<String, Object> result = new HashMap<String, Object>();
        params = AdapterFactory.getInstance()
                .getReqParamForBefor("setReqParam,createInfo", params, request, response);//前拦截
        String execptionMsg = String.valueOf(params.get("execptionMsg"));
        if (StrUtil.isNotNull(execptionMsg)) {
            ResultMsg msg = new ResultMsg("F", execptionMsg);
            return msg;
        }
        ParamsVo vo = new ParamsVo();
        vo.setParams(params);
        vo.setMethodKey("dymicSql");
        ResultEntity entity = doIusService(vo);

        result = super.getResultEntityData(entity);
        return result;
    }
     */

    /**
     * 转换application/json方式提交的数据为map对象
     * 方法参数注解声明必须：(HttpServletRequest request, HttpServletResponse response,@RequestBody Map<String, Object> requestBody)
     */
    public Map<String, String> getParameterMapByJson(HttpServletRequest request,Map<String, Object> requestBody) throws IOException {
        log.info("request body data transform before--> " + requestBody);
        Map<String, String> paramMap = new HashMap();

        String reqIp = RequestTools.getIp(request);
        paramMap.put("Client-IP", reqIp);
        paramMap.put("sysPass", ConfigUtil.getInstance().interfacePass());

        Set keSet = requestBody.entrySet();
        for (Iterator itr = keSet.iterator(); itr.hasNext();) {
            Map.Entry me = (Map.Entry) itr.next();
            String key = String.valueOf(me.getKey());
            Object ov = me.getValue();
            String value = "";
            if(ov instanceof List){
                List list = (List) ov;
                for(int i = 0; i < list.size(); i++) {
                    Map<String,String> objMap = (Map<String,String>)list.get(i);
                    Set keSet2 = objMap.entrySet();
                    for (Iterator itr2 = keSet2.iterator(); itr2.hasNext();) {
                        Map.Entry me2 = (Map.Entry) itr2.next();
                        String key2 = String.valueOf(me2.getKey());
                        Object value2 = me2.getValue();

                        String keys = key+"."+key2;
                        String values = "";
                        if(paramMap.containsKey(keys)){
                            values = paramMap.get(keys)+"-#-";
                        }
                        values +=String.valueOf(value2);
                        paramMap.put(keys, values);
                    }

                }
            }else if(ov instanceof Map){
                Map<String,Object> reqMap = (Map<String,Object>)ov;
                Set set2 = reqMap.entrySet();
                for (Iterator itr2 = set2.iterator(); itr2.hasNext();) {
                    Map.Entry me2 = (Map.Entry) itr2.next();
                    String key2 = String.valueOf(me2.getKey());
                    Object value2 = me2.getValue();
                    String keys = key+"."+key2;
                    String values = String.valueOf(value2);
                    paramMap.put(keys, values);
                }
            } else {
                value = String.valueOf(ov);
                if (StrUtil.isNotNull(value)) {
                    String str = new String(value.getBytes("iso8859-1"), "iso8859-1");
                    if (value.equals(str)) {
                        value = str;
                    }
                    paramMap.put(key,value);
                } else if (key.indexOf("s_") != -1) {
                    paramMap.put(key, "is null");
                }
            }
        }
        log.info("request body data transform after--> " + paramMap);
        return paramMap;
    }



}
